package com.finance.cooperate.common.utils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName DateUtils
 * @Description 日期时间操作工具类
 * @Author shen
 * @Date 2022/5/25 15:21
 * @Modify ...
 */
public final class DateUtils {

    //日期格式
    public static final String YYYY_MM = "yyyy-MM";
    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    public static final String YEAR = "YEAR";
    public static final String MONTH = "MONTH";
    public static final String DAY = "DAY";
    public static final String HOUR = "HOUR";



    /**
     * @Author shen
     * @Description 判断两个日期相差天数
     * @Date 11:35 上午 2020/11/11
     * @Param [date]
     * @return long
     **/
    public static Integer getTimeDiffDays(Date date1, Date date2) {

        if (date1 != null && date2 != null) {
            int days = (int) ((date2.getTime() - date1.getTime()) / (1000*3600*24));
            return days;
        }

        return null;
    }

    /**
     * @Author shen
     * @Description 判断两个日期相差天数
     * @Date 11:35 上午 2020/11/11
     * @Param [date]
     * @return long
     **/
    public static Integer getTimeDiffDays(Long millis1, Long millis2) {
        return getTimeDiffDays(getDate(millis1), getDate(millis2));
    }

    /**
     * @Author shen
     * @Description 判断两个日期相差小时数
     * @Date 6:03 下午 2021/2/22
     * @Param [millis1, millis2]
     * @return java.lang.Integer
     **/
    public static Integer getTimeDiffHours(Long millis1, Long millis2) {
        return getTimeDiffHours(getDate(millis1), getDate(millis2));
    }


    /**
     * 获取当前时间前 N 天的天数
     * @param days
     * @return
     */
    public static Date getBeforeDiffDayDate(long days) {

        return getDate(getMillis() - days * 1000 * 3600 * 24);
    }



    /**
     * @Author shen
     * @Description 判断两个日期相差小时
     * @Date 11:35 上午 2020/11/11
     * @Param [date]
     * @return long
     **/
    public static Integer getTimeDiffHours(Date date1, Date date2) {

        if (date1 != null && date2 != null) {
            int days = (int) ((date2.getTime() - date1.getTime()) / (1000*3600));
            return days;
        }
        return null;
    }


    /**
     * @Author shen
     * @Description 判断指定日期距离今天的天数
     * @Date 11:35 上午 2020/11/11
     * @Param [date]
     * @return long
     **/
    public static Integer getTimeDiffDays2Nowadays(Date date) {
        return getTimeDiffDays(date, new Date());
    }

    /**
     * @Author shen
     * @Description 判断指定日期距离今天的天数
     * @Date 11:35 上午 2020/11/11
     * @Param [date]
     * @return long
     **/
    public static Integer getTimeDiffDays2Nowadays(Long millis) {
        return getTimeDiffDays2Nowadays(getDate(millis));
    }


    /**
     * @Author shen
     * @Description 根据时间获取时间戳
     * @Date 11:35 上午 2020/5/14
     * @Param [date]
     * @return long
     **/
    public static long getMillis(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.getTimeInMillis();
    }

    /**
     * @Author shen
     * @Description 根据获取当前时间时间戳
     * @Date 11:35 上午 2020/5/14
     * @Param []
     * @return long
     **/
    public static long getMillis() {
        return getMillis(new Date());
    }


    /**
     * @Author shen
     * @Description 根据时间获取时间戳
     * @Date 11:35 上午 2020/5/14
     * @Param [date]
     * @return long
     **/
    public static long getMillis10(Date date) {

        Calendar c = Calendar.getInstance();
        c.setTime(date);

        long millis = c.getTimeInMillis();

        String value = String.valueOf(millis);

        value = String.valueOf(millis).substring(0, value.length() - 3);


        return Long.parseLong(value);
    }


    /**
     * @Author shen
     * @Description 加减小时数
     * @Date 4:52 下午 2022/3/28
     * @Param [date, i]
     * @return java.util.Date
     **/
    public static Date addHour(Date date, int i){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.HOUR_OF_DAY, i);
        return c.getTime();
    }


    /**
     * @Author shen
     * @Description 加减分钟数
     * @Date 14:15 2022/7/18
     * @Param [date, i]
     * @return java.util.Date
     **/
    public static Date addMinute(Date date, int i){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, i);
        return c.getTime();
    }


    /**
     * @Author shen
     * @Description 根据获取当前时间时间戳
     * @Date 11:35 上午 2020/5/14
     * @Param []
     * @return long
     **/
    public static long getMillis10() {
        return getMillis10(new Date());
    }


    /**
     * @Author shen
     * @Description 获取当前数据库时间戳
     * @Date 4:58 下午 2021/3/11
     * @Param []
     * @return java.sql.Timestamp
     **/
    public static Timestamp getTimestamp() {
        return getTimestamp(new Date());
    }

    /**
     * @Author shen
     * @Description 将Java 日期转为数据库时间戳
     * @Date 4:57 下午 2021/3/11
     * @Param [date]
     * @return java.sql.Timestamp
     **/
    public static Timestamp getTimestamp(Date date) {
        return new Timestamp(date.getTime());
    }

    /**
     * @Author shen
     * @Description 根据时间戳获取时间
     * @Date 11:41 上午 2020/5/14
     * @Param [millis]
     * @return java.util.Date
     **/
    public static Date getDate(Long millis){

        if (millis == null) {
            return null;
        }

        String str = millis + "";

        int strSize = 13 - str.length();

        // 补0
        int patch = 1;

        if (strSize > 0 && strSize < 3) {

            for (int i = 0; i < strSize; i ++) {
                patch *= 10;
            }
        } else if (strSize >= 3) {
            patch = 1000;
        }

        return new Date(millis * patch);

    }

    public static String toStr(Date date) {
        return toStr(date, YYYY_MM_DD_HH_MM_SS);
    }

    public static String toStr(Date date, String pattern) {
        String date2 = "";

        if (isEmpty(pattern)) {
            pattern = YYYY_MM_DD_HH_MM_SS;
        }

        if (date != null && !date.equals("")) {
            SimpleDateFormat sdf = new SimpleDateFormat(pattern);
            date2 = sdf.format(date);
        }

        return date2;
    }


    /**
     * @Author shen
     * @Description 获取时间格式："yyyy-MM-dd"
     * @Date 3:55 下午 2022/3/14
     * @Param [date]
     * @return java.util.Date
     **/
    public static Date toDate(String date) {

        return toDate(date, YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * @Author shen
     * @Description 日期的字符串格式转Date对象实例
     * @Date 3:55 下午 2022/3/14
     * @Param [date, pattern]
     * @return java.util.Date
     **/
    public static Date toDate(String date, String pattern) {
        Date date2;

        if (isEmpty(pattern)) {
            pattern = YYYY_MM_DD_HH_MM_SS;
        }

        try {
            if (date != null && !date.equals("")) {
                SimpleDateFormat sdf = new SimpleDateFormat(pattern);
                date2 = sdf.parse(date);
            } else {
                date2 = toLocalDate(new Date(), pattern);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new Date();
        }
        return date2;
    }


    /**
     * @Author shen
     * @Description 其他地区时间转成北京时间
     * @Date 3:56 下午 2022/3/14
     * @Param [date, pattern]
     * @return java.util.Date
     **/
    public static Date toLocalDate(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        TimeZone zone = new SimpleTimeZone(28800000, "Asia/Shanghai");// +8区
        sdf.setTimeZone(zone);
        String sdate = sdf.format(date);

        SimpleDateFormat sdf2 = new SimpleDateFormat(pattern);
        try {
            return sdf2.parse(sdate);
        } catch (Exception e) {
            e.printStackTrace();
            return new Date();
        }
    }



    /**
     * 获取当前天最小时间00.00.00
     * @param date
     * @return
     */
    public static Date getMinDayDateTime(Date date) {
        // 获取Calendar
        Calendar calendar = Calendar.getInstance();
        // 设置时间,当前时间不用设置
        calendar.setTime(date);
        SimpleDateFormat currentdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String setstr = currentdf.format(date).substring(0,8)+"000000";
        try {
            date=currentdf.parse(setstr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }



    /**
     * @Author shen
     * @Description 获取当月第一天
     * @Date 5:18 下午 2021/3/17
     * @Param [date]
     * @return java.util.Date
     **/
    public static Date getMinMonthDate(Date date){
        GregorianCalendar gcLast=(GregorianCalendar) Calendar.getInstance();
        gcLast.setTime(date);
        //设置为第一天
        gcLast.set(Calendar.DAY_OF_MONTH,1);
        Date day_first=gcLast.getTime();
        return day_first;
    }


    /**
     * @Author shen
     * @Description 获取当前月份最后一天
     * @Date 5:18 下午 2021/3/17
     * @Param [date]
     * @return java.util.Date
     **/
    public static Date getMaxMonthDate(Date date) {

        // 获取Calendar
        Calendar calendar = Calendar.getInstance();
        // 设置时间,当前时间不用设置
        calendar.setTime(date);
        // 设置日期为本月最大日期
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        Date setdate = calendar.getTime();
        SimpleDateFormat currentdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String setstr = currentdf.format(setdate).substring(0,8)+"235959";
        try {
            setdate=currentdf.parse(setstr);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return setdate;
    }


    /**
     * @Author shen
     * @Description 计算日期{@code startDate}与{@code endDate}的间隔天数
     * @Date 5:32 下午 2021/3/17
     * @Param [startDate, endDate]
     * @return long
     **/
//    public static long DateDiffDay(Date startDate, Date endDate) {
//
//        Instant instantStart = startDate.toInstant();
//        ZoneId zoneIdStart = ZoneId.systemDefault();
//
//        LocalDate localDateStart = instantStart.atZone(zoneIdStart).toLocalDate();
//
//
//        Instant instantEnd = startDate.toInstant();
//        ZoneId zoneIdEnd = ZoneId.systemDefault();
//
//        LocalDate localDateEnd = instantEnd.atZone(zoneIdEnd).toLocalDate();
//
//        return localDateStart.until(localDateEnd, ChronoUnit.DAYS);
//    }

    /**
     * @Author shen
     * @Description 根据时间返回年月日时间结构
     * @Date 11:43 上午 2020/5/14
     * @Param []
     * @return java.lang.String
     **/
    public static Map<String, Integer> getDateElement(Date date) {

        Map<String, Integer> result = new HashMap<>();

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        int year = calendar.get(Calendar.YEAR);
        result.put(YEAR, year);

        int month = calendar.get(Calendar.MONTH);
        result.put(MONTH, month + 1); //从0开始

        int day = calendar.get(Calendar.DATE);
        result.put(DAY, day);

        int hour = calendar.get(Calendar.HOUR);
        result.put(HOUR, hour);

        return result;
    }


    /***
     * @Author shen
     * @Description 计算年龄
     * @Date 3:59 下午 2020/6/12
     * @Param [birthday]
     * @return int
     **/
    public static Integer getAgeByBirthday(Date birthDate, Date newDate) {

        if (birthDate == null || newDate == null) {
            return null;
        }

        Calendar cal = Calendar.getInstance();

        cal.setTime(newDate);
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH) + 1;
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);

        cal.setTime(birthDate);
        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH) + 1;
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirth;

        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                // monthNow==monthBirth
                if (dayOfMonthNow < dayOfMonthBirth) {
                    age--;
                }
            } else {
                // monthNow>monthBirth
                age--;
            }
        }
        return age;
    }


    //判断字符串是否为空
    private static boolean isEmpty(String str) {
        if (str != null && str.trim().length() > 0) {
            return false;
        }
        return true;
    }

}
